﻿#include "Chapter4CompoundTypes.h"

#include <codecvt>
#include <complex>
#include <iostream>
/*·创建和使用数组。
·创建和使用C风格字符串。
·创建和使用string类字符串。
·使用方法getline()和get()读取字符串。
·混合输入字符串和数字。
·创建和使用结构。
·创建和使用共用体。
·创建和使用枚举。
·创建和使用指针。
·使用new和delete管理动态内存。
·创建动态数组。
·创建动态结构。
·自动存储、静态存储和动态存储。
·vector和array类简介。*/
using namespace std;//这个包含了#include <string>

//如果.h文件 有声明构造方法.cpp文件也要写实现.
 /*Chapter4CompoundTypes::Chapter4CompoundTypes()
{
    
};*/
    
//数组名 slifs 会被视为指向数组第一个元素的指针。这意味着当你传递 slifs 给一个函数时，
//你实际上是在传递一个指向数组第一个元素的指针，而不是整个数组本身。这是因为数组在函数参数传递时是通过指针进行的。
void eachFor(char array[], int size) {
    for (int i = 0; i < size; ++i) {
        std::cout << array[i] << ' ';
    }
}
//day1 学习oop的壁垒复合类型。array
 void Chapter4CompoundTypes::testArray()
{
    short array[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14};
    //sizeof(array)：这个表达式返回整个数组 array 占用的内存大小（以字节为单位）。
    //sizeof(array[0])：这个表达式返回数组中单个元素占用的内存大小（以字节为单位）。
    int num_elements = sizeof(array)/sizeof(array[0]);
    cout << num_elements <<"个元素,在array[]中"<<'\n';
    cout << array[1]<< '\n';
    //收缩转化不被准许
    //long plifs[]={25,92,3.0};
    char slifs[5]={'h','i',112,'\0',112};
    //使用cout打印会出现'\0'结束
 
    cout << slifs << '\n';
    int slifs_elements = sizeof(slifs)/sizeof(slifs[0]);
    eachFor(slifs,slifs_elements);

}
//4.2字符串
void Chapter4CompoundTypes::testStringCout()
{
    //字符串方式声明
    char array[]="Mr. zang";
    // cout <<底层写了循环遍历，遇到\0或者\n会结束
    cout << array << '\n';
    
    // 输出包含 \0 的字符串，这不会导致换行，而是字符串的结束
    //cout << "Hello, World!\0This will not be printed." << '\n';
    
    //在定义数组的时候，如果初始化。没有使用的位置会被默认写成\0
    char array1[8]={'1','2','3','4','5','6','\0','\0'};
    cout <<"array1[8]:"<< array1 << '\n';
    cout <<"array1首位:"<< array1[0] << '\n';
    //通过改变字符\0做字符截断;
    array1[3]='\0';
    cout <<"array1前三位"<< array1 << '\n';
    cout <<"array1长度"<< sizeof(array1) << '\n';
    //返回数组字符长度.而不是初始化长度,也不会统计空字符\0
    cout <<"array1长度"<< strlen("12 3\0_456") << '\n';
    
    //字符串拼接
    /*cout <<"i'd give my right arm to be" " a great violinist.\n";
    cout <<"i'd give my right arm to be a great violinist.\n";
    cout <<"i'd give my right a"
           "rm to be a great violinist.\n";*/
}
//如果输入有空格,cin会把空格后面的字符存放数组中，填写到第二个输出空
void Chapter4CompoundTypes::testStringCin()
{
    const int ArSize = 20;
    char name[ArSize];
    char dessert[ArSize];
    cout<<"Enter your name\n";
    cin>>name;//输入zyf
    //读取并丢到换行符(回车)
    //cin.get();
    cout<<"Enter your dessert\n";
    //getline()弊端,会是读到有换行直接结束
    cin.getline(dessert,ArSize);
    cout<<"I have some delicious "<<dessert;
    cout<<" for you, "<<name<<".\n";

    //面相行的输入getline()
    /*cin.getline(name,ArSize);
    cin.getline(dessert,ArSize);
    cout<<"I have some delicious "<<dessert;
    cout<<" for you, "<<name<<".\n";*/
    
    //getline 可以这样写,调用两次
    /*cin.getline(name,ArSize).getline(dessert,ArSize);
    cout<<"I have some delicious "<<dessert;
    cout<<" for you, "<<name<<".\n";*/
    
    //面相行的输入get
    //第一个get的方式与getline相同
    /*cin.get(dessert,ArSize);
    cout<<"I have some delicious "<<dessert;
    //连续两次get()无法跳过换行符。会读取上一个get的。
    cin.get(name,ArSize);
    cout<<" for you, "<<name<<".\n";*/

    //为什么推荐用get,get比getline 新,而且更仔细.get和getline读取空行的机制不同.
    //如果超出位数,get会把余下的字符留在输出队列.getline会设置失效位,关闭后面的输入.
    //在前一条getline()或者get()结束读取的位置开始读取.get在读取空行的时候停止运行clear()
    /*cin.get(name,ArSize).get();
    cin.get(dessert,ArSize).get();
    cout << name << '\n';
    cout << dessert;*/
}

//strcpy()过期,strncpy()不安全编译器会警告关闭也不成还是换了一个,strncpy()_s可以但是不能连续调用两次
//C11 标准最推荐使用的strcat();
void Chapter4CompoundTypes::testString()
{
    string str1 = "吃饭 ";
    string str2 = "睡觉 ";
    string str3 = "打豆豆 ";
    //string 加法运算，拼接
    /*str2+=str1;
    str3 += str2;
    cout<<"zyf's plays: "<<str2<<'\n';
    cout<<"pang's plays: "<<str3<<'\n';*/

    //strcpy(str1,str2)已经弃用了。改用strncpy()_s
    char arg2[20];
    char arg1[20] = "zyf ";
    strncpy_s(arg2,sizeof(arg2),arg1,5);
    //不能连续两次使用strncpy_s。因为没有结尾符号。缓冲区会被覆盖。
    //strncpy_s(arg2,sizeof(arg2)," pang",15);
    
    //最常用的字符串拼接用strcat
    strcat_s(arg2,sizeof(arg2),"pang");
    str2 = "zyf ";
    str2 = str2 + "pang";
    
    //sizeof 适用于计算数组或类型的大小，而不是字符串的长度。
    //str2.size() 是C++中 std::string 类型的成员函数，用于获取字符串的长度。
    //strlen(arg2) 是C标准库函数，用于获取以空字符结尾的C字符串的长度。
    int len1 = strlen(arg2);
    int len2 =  (int)str2.size();
    cout<<"arg1: "<<arg2<<", arg1 length : "<<len1<<'\n';
    cout<<"str2: "<<str2<<", str2 length : "<<len2<<'\n';
    
};
void Chapter4CompoundTypes::testStringIO()
{
    
    //char charr[20];charr 是一个字符数组，但是您没有给它一个以空字符结尾的字符串初始化。因此，这个数组的内容是不确定的，它可能包含任何垃圾值。

    char charr[20]="";
    cout<<strlen(charr)<<'\n';
    string str1;//="123/n\"\"" 使用\输入特殊字符。
    cout<<str1<<'\n';
    cout<<str1.size()<<'\n';
    /*cout<<"enter a line of text: \n";
    //
    cin.getline(charr,20);
    
    cout<<"you enter charr: "<<charr<<'\n';
    cout<<"enter another line of text: \n";
    //getline() 函数在 <string> 头文件中进行了重载
    getline(cin,str1);
    cout<<"you enter :"<<str1<<'\n';
    cout<<"length of string in cahrr after input: "<<strlen(charr)<<'\n';
    cout<<"length of string in cahrr after input: "<<str1.size()<<'\n';
    //c++设计之初有double、int和其他基本类型的类方法。没有设计string对象的类方法，
    cin>>str1;
    cout<<"处理string类的一个友元函数。在第十一章介绍: "<<str1<<'\n';*/
    
    //其他类型的char
    // 设置locale以正确处理宽字符
    
    wchar_t title[] =L"chief Astrogator";
    char16_t name[] =u"Felonia Ripova";
    char32_t car[] =U"Humber Super Snipe";
    // 打印wchar_t字符串
    std::wcout << title << '\n';
    cout<<name<<'\n';
    cout<<car<<'\n';
};

void Chapter4CompoundTypes::testStruct()
{


    std::tm timeStruct;
    /*timeStruct.tm_year = 2024 - 1900; // 年份，从1900年开始
    timeStruct.tm_mon = 12 - 1;       // 月份，从0开始计数
    timeStruct.tm_mday = 0 - 31;           // 月份中的日期
    timeStruct.tm_hour = 0 - 24;          // 小时
    timeStruct.tm_min = 0 - 59;            // 分钟
    timeStruct.tm_sec = 0 - 59;            // 秒*/
    
    struct inflatable{
    char name[20];
    float volume;
    double price;
    tm timeStruct ;
    };
     inflatable guest = {
        "Glorious Gloria",
         1.88,
         29.99,
         50,
         11,
         14,
         4,
         12,
         2024
     };
    cout<<"guest name: "<<guest.name<<'\n';
    cout<<"guest volume : "<<guest.volume<<'\n';
    cout<<"guest price : "<<guest.price<<'\n';
    cout<<"guest time : "<<guest.timeStruct.tm_year<<"/"<<guest.timeStruct.tm_mon<<"/"<<guest.timeStruct.tm_mday<<char(32);
    cout<<guest.timeStruct.tm_hour<<":"<<guest.timeStruct.tm_min<<":"<<guest.timeStruct.tm_sec<<'\n';
    
};

/*int main()
{   Chapter4CompoundTypes chapter4;
    //chapter4.testArray();
    //chapter4.testStringCout();
    //chapter4.testStringCin();
    //chapter4.testString();
    //chapter4.testStringIO();
    chapter4.testStruct();
    return 1;
}*/